﻿using ImTools;
using IntoTheVoid.Models;
using IntoTheVoid.Units;
using Microsoft.VisualBasic.FileIO;
using SevenZip;
using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace IntoTheVoid.State
{
	public class InstallState : State
	{
		public Task InstallTask;
		public string zipPath;
		public string zipDiffInfoJsonName;

		decimal installProgress = 0;

		private readonly string DIC_NAME = @"IntoTheVoid\";
		private readonly string EXE_NAME = @"IntoTheVoid.exe";
		public InstallState(string path, StateContext context)
		{
			context.StateType = StateType.Installing;
			Context = context;
			buttonContent = "  安装中";
			buttonEnabla = false;
			Context.OnButtonStateArgs(new ButtonStateChangeEventArgs(buttonContent, buttonEnabla, true, false, "StartDownloadButtonGray"));
			zipPath = path;

			InstallServer();
			if (InstallTask == null)
			{
				InstallTask = Task.Factory.StartNew(delegate
				{
					if (!ExtractZip(zipPath))
					{
						ExtractErrorDeal(zipPath);
					}
					InstallTask = null;
				});
			}
		}

		private bool ExtractZip(string zipPath)
		{
			bool result = false;

			var defaultPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Game");
			var targetPath = BaseInfoContentModel.Instance.GetValue<string>("gameInstallPath", defaultPath);
			zipDiffInfoJsonName = System.IO.Path.Combine(targetPath, "IntoTheVoid", "diff_info.json");

			Context.OnProcessStateArgs(new ProcessStateChangeEventArgs(0, "", "", ""));
			using (SevenZipExtractor extr = new SevenZipExtractor(zipPath))
			{
				var path = Path.Combine(targetPath, DIC_NAME);
				LogHelper.Info("Extract file:" + zipPath);

				extr.Extracting += new EventHandler<ProgressEventArgs>(Extracting);
				extr.ExtractionFinished += Extr_ExtractionFinished;
				try
				{
					extr.ExtractArchive(path);
				}
				catch (Exception ex)
				{
					LogHelper.Error(ex, "ExtractArchive Error:" + zipPath);
					return result;
				}
			}

			if (File.Exists(zipPath))
			{
				try
				{
					File.Delete(zipPath);
				}
				catch (Exception ex)
				{
					LogHelper.Error(ex, "File Delete Error:" + zipPath);
				}
			}

			var version = Path.GetFileNameWithoutExtension(zipPath);
			LogHelper.Info("FileName:" + zipPath);

			// 更新的文件名文件格式1.0.0_1.0.1_diff.zip
			if (version.Contains("diff"))
			{
				var vec = version.Split('_');
				if (vec.Length == 3)
					version = vec[1];
				else
					version = "1.0.0";
			}
			else
			{
				if (version.IndexOf('_') == -1)
					LogHelper.Error("FileNameError:" + zipPath);
				else
					version = version.Substring(0, version.IndexOf('_'));
			}

			var filename = version + "_info.json";
			var fileInfoJson = System.IO.Path.Combine(targetPath, "IntoTheVoid", filename);
			BaseInfoContentModel.Instance.SetValue("fileInfoJson", fileInfoJson);

			result = true;
			return result;
		}

		private void Extr_ExtractionFinished(object sender, EventArgs e)
		{
			SaveDownLoadCompletedParameter();
			if (File.Exists(zipDiffInfoJsonName))
			{
				//Context.StateType = StateType.FileChecking;
				//Context.CurState = new FileCheckState(Context, zipDiffInfoJsonName);
				// FileCheckState.FileCheckDeleteFile(zipDiffInfoJsonName);
				Context.StateType = StateType.CanOpenGame;
				Context.CurState = new OpenGameState(Context);
			}
			else
			{
				// 写注册表
				Common.SaveTapReg();
				LogHelper.Warn("FilesInfoJson is not exist:" + zipDiffInfoJsonName);
				Context.StateType = StateType.CanOpenGame;
				Context.CurState = new OpenGameState(Context);
			}


		}
		private void SaveDownLoadCompletedParameter()
		{
			var httpDownLoadInfo = GameDownloadConfigModel.Instance.DownLoadInfo;
			BaseInfoContentModel.Instance.SetValue("btnStage", BtnStage.Play);
			BaseInfoContentModel.Instance.SetValue("version", httpDownLoadInfo.OpenedLatest);
		}
		private void Extracting(object sender, ProgressEventArgs e)
		{
			installProgress += e.PercentDelta;
			Context.OnProcessStateArgs(new ProcessStateChangeEventArgs((double)installProgress, "资源解压中...", "", ""));
		}

		private void InstallServer()
		{
			LogHelper.Info(AppDomain.CurrentDomain.BaseDirectory);
			string sevenDll = AppDomain.CurrentDomain.BaseDirectory + "7z64.dll";
			SevenZipExtractor.SetLibraryPath(sevenDll);
		}
		private void ExtractErrorDeal(string file)
		{
			LogHelper.Error("下载文件损坏");
			if (File.Exists(file))
			{
				try
				{
					File.Delete(file);
				}
				catch (Exception ex)
				{
					LogHelper.Error("下载文件损坏, 删除文件错误" + ex.Message);
				}
			}

			Context.OnTipsStateArgs(new TipsEventArgs("检测到下载文件损坏，请重新尝试下载"));
			// Common.ClearDownloadFile();
			Context.StateType = StateType.NeedDownload;
			Context.CurState = new DownloadState(Context);
		}

	}
}
